﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Windows.UI.Xaml.Media.Imaging;
using SQLite;
using wBudget.Common;
using wBudget.Models;
using Windows.Storage;
using System.ComponentModel;

namespace wBudget
{
    public static class DataManager
    {
        static readonly String File = Path.Combine(ApplicationData.Current.RoamingFolder.Path, "budget.sqlite");
        public static List<Category> Categories { get; private set; }
        public static List<Entry> Entries{ get; private set; }
        public static SortedDictionary<int, BitmapImage> CategoryLogos;
        private static Settings settings;

        public static bool UseCustomCurrency
        {
            get
            {
                return settings.UseCustomCurrency;
            }
            set
            {
                settings.UseCustomCurrency = value;
                using (var db = new SQLiteConnection(File))
                {
                    db.Update(settings);
                }
            }
        }

        public static string CurrencyString {
            get 
            { 
                return settings.CurrencyString; 
            }
            set 
            { 
                settings.CurrencyString = value;
                using (var db = new SQLiteConnection(File))
                {
                    db.Update(settings);
                }
            }
        }

        public async static void Init() 
        {
            Categories = new List<Category>();
            Entries = new List<Entry>();
            CategoryLogos = new SortedDictionary<int, BitmapImage>();

            using (var db = new SQLiteConnection(File))
            {
                db.CreateTable<Category>();
                db.CreateTable<Entry>();
                db.CreateTable<Settings>();
                Categories = db.Query<Category>("SELECT * FROM Category");
                Entries = db.Query<Entry>("SELECT * FROM Entry");
                List<Settings> settingsList = db.Query<Settings>("SELECT * FROM Settings");
                if (settingsList.Count == 0)
                {
                    settingsList.Add(new Settings() {UseCustomCurrency = true, CurrencyString = "€", DummyPK = 1});
                    db.InsertAll(settingsList);
                }
                settings = settingsList[0];
                if (Categories.Count == 0)
                {
                    AddSampleData();
                    db.InsertAll(Entries);
                    db.InsertAll(Categories);
                }
            }

            foreach (Category c in Categories)
            {
                DataManager.CategoryLogos.Add(c.Id, await ImageLoader.LoadImage(c.BImage));
            }
        }

        public static void AddSampleData()
        {
            Categories.Add(new Category { Title = "Food", Id = 1 , BImage = "Assets/logos/Soup-01.png" });
            Categories.Add(new Category { Title = "Electricity", Id = 2, BImage = "Assets/logos/Shape-Lightning.png" });
            Categories.Add(new Category { Title = "Rent", Id = 3, BImage = "Assets/logos/MoneyOut.png" });
            Categories.Add(new Category { Title = "Income", Id = 4, BImage = "Assets/logos/MoneyIn.png" });

            var e = new Entry { CategoryId = 1, Date = DateTime.Now, Amount = -200.2, Description = "150 * some food" };
            Entries.Add(e);
            e = new Entry { CategoryId = 2, Date = DateTime.Now, Amount = -20.2, Description = "Electricity bill" };
            Entries.Add(e);
            e = new Entry { CategoryId = 3, Date = DateTime.Now, Amount = -300.2, Description = "Rent" };
            Entries.Add(e);
            e = new Entry { CategoryId = 1, Date = DateTime.Now, Amount = -250.2, Description = "150 * more food" };
            Entries.Add(e);
            e = new Entry { CategoryId = 4, Date = DateTime.Now, Amount = 1250.2, Description = "Salary" };
            Entries.Add(e);
            e = new Entry { CategoryId = 2, Date = DateTime.Now, Amount = 20.2, Description = "Payback of last months electricity bill" };
            Entries.Add(e);
        }

        public static int GetHighestCategoryId()
        {

            var result = from category in Categories
                         where Categories.All(p => p.Id <= category.Id)
                         select category.Id;
            return result.ToArray().Length > 0 ? result.ToArray()[0] : 1;
        }

        public static void Add(Entry entry)
        {
            using (var db = new SQLiteConnection(File))
            {
                db.Insert(entry);
            }
            Entries.Add(entry);
        }

        public static void Add(Category category)
        {
            using (var db = new SQLiteConnection(File))
            {
                db.Insert(category);
            }
            Categories.Add(category);
            CategoryLogos.Add(category.Id, ImageLoader.LoadImage(category.BImage).Result);
        }

        public static List<Entry> GetEntriesForCategories(List<Category> list)
        {
            if (list.Count == 0)
            {
                return Entries;
            }
            var result =
               from entry in Entries
               where list.Any(p => p.Id == entry.CategoryId)
               select entry;
            return result.ToList();
        }

        public static Category GetCategoryForId(int id)
        {
            return Categories.Find(delegate(Category c) { return c.Id == id; });
        }
    }
}
